

#include "NodeLeftParenth.h"

NodeLeftParenth::NodeLeftParenth()
: Node(QString("parentheses"), 1, QString("()")) {
    // add the layout
    QHBoxLayout* layout = new QHBoxLayout(this);
    layout->setSpacing(1);
    layout->setContentsMargins(1, 1, 1, 1);

    // set index to place child node at
    m_index = 1;

    // add the label (
    EditOperator* lab1 = new EditOperator(this);
    lab1->setObjectName("left_parentheses");
    lab1->setText("(");
    layout->addWidget(lab1);
    // add the label )
    EditOperator* lab2 = new EditOperator(this);
    lab2->setObjectName("right_parentheses");
    lab2->setText(")");
    layout->addWidget(lab2);
}

QString NodeLeftParenth::toCasString() const {
    Q_ASSERT_X(getSingleChild() != 0, "",
            "Could not find single child node.");
    Q_ASSERT_X(numChildren() == 1, "", "Expected one child.");

    QString str;
    str.append("(");
    str.append(getSingleChild()->toCasString());
    str.append(")");
    return str;
}

QString NodeLeftParenth::toPrintString() const {
    Q_ASSERT_X(getSingleChild() != 0, "",
            "Could not find single child node.");
    Q_ASSERT_X(numChildren() == 1, "", "Expected one child.");

    QString str;
    str.append("(");
    if (getSingleChild()->getNodeType() == "empty") str.append("_");
    else str.append(getSingleChild()->toPrintString());
    str.append(")");
    return str;
}

QString NodeLeftParenth::toParseString() const {
    Q_ASSERT_X(getSingleChild() != 0, "",
            "Could not find single child node.");
    Q_ASSERT_X(numChildren() == 1, "", "Expected one child.");

    QString str;
    str.append("(");
    str.append(getSingleChild()->toParseString());
    str.append(")");
    return str;
}

int NodeLeftParenth::getInputPosition(bool& found) const {
    int counter = 0;

    // look it left parentheses label/lineedit
    if (leftPar()->hasFocus() and not found) {
        found = true;
        counter += leftPar()->cursorPosition();
    } else if (not found) {
        counter += leftPar()->text().size();
    }
    
    // pass to child node
    if (not found) counter += getSingleChild()->getInputPosition(found);
    
    // look it right parentheses label/lineedit
    if (rightPar()->hasFocus() and not found) {
        found = true;
        counter += rightPar()->cursorPosition();
    } else if (not found) {
        counter += rightPar()->text().size();
    }
    
    return counter;
}

void NodeLeftParenth::setInputPosition(int& position) {
    Q_ASSERT_X(getSingleChild() != 0, "",
            "Could not find single child node.");
    Q_ASSERT_X(numChildren() == 1, "",
            "Expected one child.");

    // if position falls into left parentheses node place it
    if (position == 0 or position == 1) {
        leftPar()->setFocus();
        leftPar()->setCursorPosition(position);
    }
    --position;

    if (position >= 0) getSingleChild()->setInputPosition(position);

    // if position falls into right parentheses node place it
    // but only if it has not been placed ie is greater then 0
    if (position == 1) {
        rightPar()->setFocus();
        rightPar()->setCursorPosition(position);
    }
    --position;
}

EditOperator * NodeLeftParenth::leftPar() {
    Q_ASSERT_X(findDirectChild<EditOperator *>("left_parentheses"), "",
            "Unable to find left label.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("left_parentheses")->text().size() == 1
            , "", "Left label size is not one.");
    return findDirectChild<EditOperator *>("left_parentheses");
}

EditOperator * NodeLeftParenth::rightPar() {
    Q_ASSERT_X(findDirectChild<EditOperator *>("right_parentheses"), "",
            "Unable to find right label.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("right_parentheses")->text().size() == 1
            , "", "Right label size is not one.");
    return findDirectChild<EditOperator *>("right_parentheses");
}

const EditOperator * NodeLeftParenth::leftPar() const {
    Q_ASSERT_X(findDirectChild<EditOperator *>("left_parentheses"), "",
            "Unable to find left label.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("left_parentheses")->text().size() == 1
            , "", "Left label size is not one.");
    return findDirectChild<EditOperator *>("left_parentheses");
}

const EditOperator * NodeLeftParenth::rightPar() const {
    Q_ASSERT_X(findDirectChild<EditOperator *>("right_parentheses"), "",
            "Unable to find right label.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("right_parentheses")->text().size() == 1
            , "", "Right label size is not one.");
    return findDirectChild<EditOperator *>("right_parentheses");
}
